package epay18

import (
	"context"
	"encoding/json"
	"navi-mumbai/app/rpc/pay/pb"
	pb2 "navi-mumbai/app/rpc/wallet/pb"
	"navi-mumbai/common/key/paykey"
	"navi-mumbai/common/key/walletkey"
	"navi-mumbai/third/pay/epay18"
	"strconv"

	"navi-mumbai/app/api/pay/internal/svc"
	"navi-mumbai/app/api/pay/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type DepositNotifyEpay18Logic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewDepositNotifyEpay18Logic(ctx context.Context, svcCtx *svc.ServiceContext) *DepositNotifyEpay18Logic {
	return &DepositNotifyEpay18Logic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *DepositNotifyEpay18Logic) DepositNotifyEpay18(req *types.WithdrawNotifyEpay18Req) (resp *types.WithdrawNotifyEpay18Resp, err error) {
	if req.Content == "" {
		l.Logger.Errorf("DepositNotifyEpay18Logic req.Content is empty")
		return
	}
	var reqContent types.DepositNotifyEpay18ReqContent
	err = json.Unmarshal([]byte(req.Content), &reqContent)
	if err != nil {
		l.Logger.Errorf("DepositNotifyEpay18Logic json.Unmarshal(req.Content:%s) error(%v)", req.Content, err)
		return
	}

	// 校验签名
	sign := epay18.Md5v(reqContent.Amount + l.svcCtx.Config.PayChannelEPay18Conf.MerchantCode + reqContent.MerchantTradeNo + reqContent.NotifyTime + reqContent.TradeNo + reqContent.TradeStatus + l.svcCtx.Config.PayChannelEPay18Conf.MD5Key)
	if sign != reqContent.Sign {
		l.Logger.Errorf("DepositNotifyEpay18Logic sign error(%v)", err)
		return
	}

	var fn int64
	fn, err = strconv.ParseInt(reqContent.MerchantTradeNo, 10, 64)
	if err != nil {
		l.Logger.Errorf("DepositNotifyEpay18Logic strconv.ParseInt(reqContent.MerchantTradeNo:%s) error(%v)", reqContent.MerchantTradeNo, err)
		return
	}

	// 更新支付网关流水状态
	in := pb.UpdateEpay18DepositResultReq{
		PayGwFlowNo:  fn,
		TradeStatus:  reqContent.TradeStatus,
		Amount:       reqContent.Amount,
		ExFlowNo:     reqContent.TradeNo,
		NotifyTime:   reqContent.NotifyTime,
		PayChannelId: walletkey.PayChannelIdEpay18_UPI,
	}

	var rsp *pb.UpdateEpay18DepositResultResp
	rsp, err = l.svcCtx.PaySysRpc.UpdateEpay18DepositResult(l.ctx, &in)
	if err != nil {
		l.Logger.Errorf("DepositNotifyEpay18Logic svcCtx.Pay.UpdateDepositResult error(%v)", err)
		return
	}

	// 更新用户钱包余额
	var in2 pb2.UpdateDepositResultReq
	in2 = pb2.UpdateDepositResultReq{
		Uid:            rsp.Uid,
		FlowNo:         rsp.WalletFlowNo,
		State:          GetPayStateByEpayTradeStatus(reqContent.TradeStatus),
		ExternalFlowNo: reqContent.TradeNo,
		Amount:         reqContent.Amount,
		ErrMsg:         "",
		PayGwFlowNo:    fn,
	}

	_, err = l.svcCtx.WalletSysRpc.UpdateDepositResult(l.ctx, &in2)
	if err != nil {
		l.Logger.Errorf("DepositNotifyEpay18Logic svcCtx.WalletSysRpc.UpdateDepositResult error(%v)", err)
		return
	}
	return
}

func GetPayStateByEpayTradeStatus(ts string) int64 {
	switch ts {
	case paykey.Epay18PayStatusDepositSuccess:
		return walletkey.DepositFlowStateSuccess
	case paykey.Epay18PayStatusWithdrawSuccess:
		return walletkey.WithdrawFlowStateSuccess
	case paykey.Epay18PayStatusDepositWait:
		return walletkey.DepositFlowStateWait
	case paykey.Epay18PayStatusDepositFail:
		return walletkey.DepositFlowStateFailed
	case paykey.Epay18PayStatusWithdrawWait:
		return walletkey.WithdrawFlowStateStart
	case paykey.Epay18PayStatusWithdrawFail:
		return walletkey.WithdrawFlowStateFailed
	default:
		return 0
	}
}
